""" from custom_components.smarthome_voice_assistant.set_service import ServiceData
from custom_components.smarthome_voice_assistant.deviceLib import const """
import json
import logging

_LOGGER = logging.getLogger(__name__)

from .utils import get_mac_addr
from .mqtt import MqttClient

from homeassistant.const import (ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME,
                                 ATTR_DOMAIN, CONF_USERNAME, CONF_PASSWORD,
                                 CONF_DEVICES, EVENT_STATE_CHANGED)
from homeassistant.core import callback
from homeassistant.loader import bind_hass
from .const import (pub_topic)

from .set_service import SetServiceData

from .get_value import GetProps


#from . import climate
class VioceApp(MqttClient):
    def __init__(self, hass, entry) -> None:
        super().__init__(hass, entry.data[CONF_USERNAME], entry.data[CONF_PASSWORD],entry.data['uid'])
        self.dev_list = None
        self.devices = self._update_devices(entry.data[CONF_DEVICES])
        self.hass = hass
        self._entry = entry
        entry.async_on_unload(entry.add_update_listener(self.update_listener))

    def _update_devices(self,data):
        #_LOGGER.error(data)
        return [dev.split('/')[0] for dev in data] 

    async def update_listener(self,hass, entry):
        self.devices = self._update_devices(entry.data[CONF_DEVICES])
        await self.get_devices()

    async def ha_state_changed(self, event):
        """状态变化"""
        if not self.dev_list:
            await self.get_devices()

        for obj in self.dev_list:
            if obj[ATTR_ENTITY_ID] != event.data[ATTR_ENTITY_ID]:
                continue
            data = self.json_loads(event.data)
            obj['attributes'] = data['new_state']['attributes']
            obj['state'] = data['new_state']['state']
            await self.publish(obj, pub_topic + self.username + '/devUpdate')
            

    async def get_devices(self):
        """获取设备列表"""
        states = self._hass.states.async_all()
        states = self.json_loads(states)  #转为字典

        tmp = []
        for state in states:
            for dev in self.devices:
                if state[ATTR_ENTITY_ID] == dev:
                    tmp.append(state)
        states = tmp

        self.dev_list = []

        i = 0
        for dev in states:
            domain = dev[ATTR_ENTITY_ID].split('.')[0]
            """加ID"""
            dev['id'] = '{}-ha-{}-{}-{}'.format(self.username, get_mac_addr(),
                                                domain, dev[ATTR_ENTITY_ID].split('.')[1])
            dev['name'] = dev['attributes'][ATTR_FRIENDLY_NAME]
            dev[ATTR_DOMAIN] = domain
            self.dev_list.append(dev)
            i = i + 1
        return self.dev_list

    async def call_service(self, service_data):
        """调用HA服务"""
        #_LOGGER.warning(service_data.service_data)
        try:
            result = await self._hass.services.async_call(
                service_data.domain,
                service_data.service,
                service_data.service_data,
                blocking=True)
            if result == True:
                return 0
            else:
                return -1
        except Exception as e:
            _LOGGER.error(e)
            return -1

    def get_cur_state(self, id):
        """获取当前状态"""
        for dev in self.dev_list:
            if id == dev['id']:
                return dev
        return None

    def get_props(self, get_info):
        """获取属性状态"""
        cur_state = self.get_cur_state(get_info['id'])
        if not cur_state:
            return 'null'
        try:
            getProps = GetProps(cur_state)
            return getProps.get_value(get_info['name'])
        except Exception as e:
            _LOGGER.error('读取未支持的属性:' + get_info['name'])
            return 'null'

    async def set_props(self, set_data):
        """设置属性状态"""
        #_LOGGER.error(set_data)
        payload = self.get_cur_state(set_data['id'])
        if payload == None:
            return -1
        try:
            setServiceData = SetServiceData(set_data)
            data = setServiceData.set_call_service_data(payload)
            if not data:
                return -1
            return await self.call_service(data)
        except:
            _LOGGER.error('调用服务失败')
            return -1

    @callback
    async def receive_message(self, payload):

        if 'type' in payload:
            if not self.dev_list:
                await self.get_devices()
            if payload['type'] == 'getDevices':
                payload['data'] = await self.get_devices()
            elif payload['type'] == 'getProps':
                """获取属性状态"""
                for device in payload['data']:
                    device['value'] = self.get_props(device)
            elif payload['type'] == 'setProps':
                """设置状态"""
                for device in payload['data']:
                    device['status'] = await self.set_props(device)
            
        await self.publish(payload)

    @callback
    @bind_hass
    def _handle_message(self, msg):
        payload = json.loads(msg.payload.decode())
        self.hass.async_create_task(self.receive_message(payload))

    def on_message(self, client, userdata, msg):
        """接收云消息"""
        #self.hass.add_job(self._handle_message, msg)
        payload = json.loads(msg.payload.decode())
        self.hass.async_create_task(self.receive_message(payload))
